package com.luoye.lj.interceptor;

import com.luoye.lj.platform.model.UserModel;
import com.luoye.lj.platform.model.domain.manage.ManageLog;
import com.luoye.lj.platform.service.IMuserservice;
import com.luoye.lj.util.mvc.annotation.OperateLog;
import com.luoye.lj.util.mvc.log.IDescriptionGenerator;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * User:
 * Date: 15-11-4
 * Time: 下午8:52
 * To change this template use File | Settings | File Templates.
 */
@Component
public class LogInterceptor implements HandlerInterceptor {
    private Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

    @Autowired
    private IMuserservice muserservice;

    private boolean logAll=false;

    public boolean isLogAll() {
        return logAll;
    }

    public void setLogAll(boolean logAll) {
        this.logAll = logAll;
    }

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String webContext = httpServletRequest.getContextPath();
        logger.debug("LogInterceptor-preHandle-webContext->" + webContext);
        logger.debug("LogInterceptor-preHandle-o->" + o);
//        logger.info("LogInterceptor-preHandle-o->"+o.getClass().getName());
        boolean doLog=false;
        if(this.logAll){//记录所有请求
            doLog=true;
        }else{//只记录注解了的请求
            if(o instanceof HandlerMethod){
                Method method=((HandlerMethod)o).getMethod();
                if(method.isAnnotationPresent(OperateLog.class)){
                    doLog=true;
                }
            }
        }

        //先判断是否需要记录操作日志

        if(doLog){
            long userid=0;
            String username=null;
            String aurl=httpServletRequest.getServletPath();
            String aparams= JSONObject.fromObject(httpServletRequest.getParameterMap()).toString();
            String aip=getClientIp(httpServletRequest);
            String name=null;
            String description=null;
            try {
                if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof UserModel) {
                    UserModel userDetails = (UserModel) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                    logger.debug("LogInterceptor-preHandle-userDetails->" + userDetails);
                    userid = userDetails.getmUserDetail().getId();
                    username = userDetails.getmUserDetail().getUsername();
                }
                logger.debug("LogInterceptor-preHandle-description->" + description);
                if (o instanceof HandlerMethod) {
                    Method method = ((HandlerMethod) o).getMethod();
                    if (method.isAnnotationPresent(OperateLog.class)) {
                        OperateLog operateLog = method.getAnnotation(OperateLog.class);
                        name = operateLog.value();
                        description = operateLog.description();
                        Class descriptionGeneratorClass = operateLog.descriptionGenerator();
                        if (IDescriptionGenerator.class.isAssignableFrom(descriptionGeneratorClass)) {
                            IDescriptionGenerator descriptionGenerator = (IDescriptionGenerator) descriptionGeneratorClass.newInstance();
                            description = descriptionGenerator.generate(httpServletRequest, httpServletResponse, name, httpServletRequest.getParameterMap());
                            logger.debug("LogInterceptor-preHandle-description-byDescriptionGenerator->" + description);
                        }
                        String descriptionGeneratorBean = operateLog.descriptionGeneratorBean();
                        if (!StringUtils.isEmpty(descriptionGeneratorBean)) {
                            WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
                            IDescriptionGenerator descriptionGenerator = (IDescriptionGenerator) webApplicationContext.getBean(descriptionGeneratorBean);
                            if (descriptionGenerator != null) {
                                description = descriptionGenerator.generate(httpServletRequest, httpServletResponse, name, httpServletRequest.getParameterMap());
                                logger.debug("LogInterceptor-preHandle-description-byDescriptionGeneratorBean->" + description);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                logger.warn(e.getMessage(),e);
            }
            ManageLog manageLog=new ManageLog();
            manageLog.setUserid(userid);
            manageLog.setUsername(username);
            manageLog.setAurl(aurl);
            manageLog.setAparams(aparams);
            manageLog.setAtime(new Date());
            manageLog.setOperatename(name);
            manageLog.setDescription(description);
            manageLog.setAip(aip);
            manageLog.setBrowser(getBrowser(httpServletRequest));

            logger.debug("LogInterceptor-log->"+manageLog);

            try {
                muserservice.insertLog(manageLog);
            } catch (Exception ex) {
                logger.warn("LogInterceptor-preHandle-发生了未知错误",ex);
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
//        logger.info("LogInterceptor-log-modelAndView->"+modelAndView);
//        logger.info("LogInterceptor-log-httpServletResponse->"+httpServletResponse);
//        logger.info("LogInterceptor-log-o->"+o);
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    private String getClientIp(HttpServletRequest request){
        String clientIp="";
        /*****获取外网ip********/
        if (!StringUtils.isEmpty(request.getHeader("X-Forwarded-For")))
            clientIp = request.getHeader("X-Forwarded-For");
        else if(!StringUtils.isEmpty(request.getHeader("X-Real-IP")))
            clientIp = request.getHeader("X-Real-IP");
        else
            clientIp = "0.0.0.0";

        /********获取内网ip**********/
        String vcip= request.getRemoteAddr();
        if(vcip==null||vcip==""){
            clientIp=clientIp+"."+"0.0.0.0";
        }else{
            clientIp=clientIp+"."+vcip;
        }
        //println "clientIp: "+clientIp
        return clientIp;
    }

    private String getBrowser(HttpServletRequest request){
        return request.getHeader("User-Agent");
    }

}
